package stegnos.tests;

import java.awt.Font;

import processing.core.*;

public class StegGraphics extends PApplet {

	float tw;
	int th;
	float baseline;	
	// Size of bit
	int bitW, bitH;

	int[] bcols;
	String[] channels = { "Alpha", "Red", "Green", "Blue" };

	int backColor, clearColor, foreColor, textColor;

	PFont pf;
	PGraphics pg;

	public void setup() {
		size(800, 1200);
		background(34);

		foreColor = color(116,246,116);
		textColor = color(0);
		clearColor = color(34,34,34,0);

		bcols = new int[] {
				color(255, 255, 200), // alpha 24-31
				color(255, 200, 200), // red 16-23
				color(200, 255, 200), // green 8-15
				color(200, 200, 255), // blue 0-7
		};

		pg = drawByte("76543210");
		image(pg,10,10);
		pg.save("data/steg/byte0.png");

		pg = drawPixel0();
		image(pg,10,50);
		pg.save("data/steg/pixel0.png");

		pg = drawPixel1();
		image(pg,10,100);
		pg.save("data/steg/pixel1.png");

		pg = drawPixel2();
		image(pg,10,150);
		pg.save("data/steg/pixel2.png");

		pg = drawPixel3();
		image(pg,10,200);
		pg.save("data/steg/pixel3.png");

		pg = drawPixel4();
		image(pg,10,250);
		pg.save("data/steg/pixel4.png");

		pg = drawPixel5();
		image(pg,10,300);
		pg.save("data/steg/pixel5.png");

		pg = drawPixel6();
		image(pg,10,350);
		pg.save("data/steg/pixel6.png");

	}

	public PGraphics drawPixel0(){
		bitW = 18;
		bitH = 16;
		th = 12;
		PGraphicsJava2D pg = (PGraphicsJava2D) createGraphics(34 * bitW, 3 * bitH, JAVA2D);
		Font font = new Font("Courier", Font.PLAIN, th);
		pg.g2.setFont(font);
		pg.smooth();
		baseline = (bitH + 0.8f * th)/2;

		pg.beginDraw();
		pg.background(clearColor);
		pg.strokeWeight(2);
		pg.stroke(foreColor);
		pg.translate(bitW, bitH);
		pg.fill(foreColor);
		int bn = 31;
		for(int ch = 0; ch < 4; ch++){
			String channel = "" + "ARGB".charAt(ch);
			for(int bit = 7; bit >= 0; bit--){
				drawBit(pg, bn--, channel + bit, bcols[ch]);
			}
		}
		font = new Font("Courier", Font.BOLD, th);
		pg.g2.setFont(font);
		for(int ch = 0; ch < 4; ch++){
			pg.fill(bcols[ch]);
			pg.text(channels[ch], ch * bitW * 8 + 3*bitW, -6);
		}		
		pg.endDraw();

		return pg;
	}

	public PGraphics drawPixel1(){
		bitW = 18;
		bitH = 16;
		th = 12;
		PGraphicsJava2D pg = (PGraphicsJava2D) createGraphics(34 * bitW, 3 * bitH, JAVA2D);
		Font font = new Font("Courier", Font.PLAIN, th);
		pg.g2.setFont(font);
		pg.smooth();
		baseline = (bitH + 0.8f * th)/2;

		pg.beginDraw();
		pg.background(clearColor);
		pg.strokeWeight(2);
		pg.stroke(foreColor);
		pg.translate(bitW, bitH);
		pg.fill(foreColor);
		int bn = 31;
		for(int ch = 0; ch < 4; ch++){
			String channel = "" + "ARGB".charAt(ch);
			for(int bit = 7; bit >= 0; bit--){
				if(bit >= 4)
					drawBit(pg, bn--, channel + bit, bcols[ch]);
				else
					drawBit(pg, bn--, "?", color(255));

			}
		}
		font = new Font("Courier", Font.BOLD, th);
		pg.g2.setFont(font);
		for(int ch = 0; ch < 4; ch++){
			pg.fill(bcols[ch]);
			pg.text(channels[ch], ch * bitW * 8 + 3*bitW, -6);
		}		
		pg.endDraw();

		return pg;
	}

	public PGraphics drawPixel2(){
		bitW = 18;
		bitH = 16;
		th = 12;
		PGraphicsJava2D pg = (PGraphicsJava2D) createGraphics(34 * bitW, 3 * bitH, JAVA2D);
		Font font = new Font("Courier", Font.PLAIN, th);
		pg.g2.setFont(font);
		pg.smooth();
		baseline = (bitH + 0.8f * th)/2;

		pg.beginDraw();
		pg.background(clearColor);
		pg.strokeWeight(2);
		pg.stroke(foreColor);
		pg.translate(bitW, bitH);
		pg.fill(foreColor);
		int bn = 31;
		for(int ch = 0; ch < 4; ch++){
			String channel = "" + "ARGB".charAt(ch);
			for(int bit = 7; bit >= 0; bit--){
				if(ch == 0 || bit >= 4)
					drawBit(pg, bn--, channel + bit, bcols[ch]);
				else
					drawBit(pg, bn--, "?", color(255));
			}
		}
		font = new Font("Courier", Font.BOLD, th);
		pg.g2.setFont(font);
		for(int ch = 0; ch < 4; ch++){
			pg.fill(bcols[ch]);
			pg.text(channels[ch], ch * bitW * 8 + 3*bitW, -6);
		}		
		pg.endDraw();

		return pg;
	}

	public PGraphics drawPixel3(){
		bitW = 18;
		bitH = 16;
		th = 12;
		PGraphicsJava2D pg = (PGraphicsJava2D) createGraphics(34 * bitW, 3 * bitH, JAVA2D);
		Font font = new Font("Courier", Font.PLAIN, th);
		pg.g2.setFont(font);
		pg.smooth();
		baseline = (bitH + 0.8f * th)/2;

		pg.beginDraw();
		pg.background(clearColor);
		pg.strokeWeight(2);
		pg.stroke(foreColor);
		pg.translate(bitW, bitH);
		pg.fill(foreColor);
		int bn = 31;
		for(int bit = 7; bit >= 0; bit--){
			for(int ch = 0; ch < 4; ch++){
				String channel = "" + "ARGB".charAt(ch);
				drawBit(pg, bn--, channel + bit, bcols[ch]);
			}
		}
		pg.endDraw();

		return pg;
	}

	public PGraphics drawPixel4(){
		bitW = 18;
		bitH = 16;
		th = 12;
		PGraphicsJava2D pg = (PGraphicsJava2D) createGraphics(34 * bitW, 3 * bitH, JAVA2D);
		Font font = new Font("Courier", Font.PLAIN, th);
		pg.g2.setFont(font);
		pg.smooth();
		baseline = (bitH + 0.8f * th)/2;

		pg.beginDraw();
		pg.background(clearColor);
		pg.strokeWeight(2);
		pg.stroke(foreColor);
		pg.translate(bitW, bitH);
		pg.fill(foreColor);
		int bn = 31;
		for(int bit = 7; bit >= 0; bit--){
			for(int ch = 1; ch < 4; ch++){
				String channel = "" + "ARGB".charAt(ch);
				drawBit(pg, bn--, channel + bit, bcols[ch]);
			}
		}
		while(bn >= 0){
			drawBit(pg, bn--, "0", color(255));
		}
		pg.endDraw();

		return pg;
	}

	public PGraphics drawPixel5(){
		bitW = 18;
		bitH = 16;
		th = 12;
		PGraphicsJava2D pg = (PGraphicsJava2D) createGraphics(34 * bitW, 3 * bitH, JAVA2D);
		Font font = new Font("Courier", Font.PLAIN, th);
		pg.g2.setFont(font);
		pg.smooth();
		baseline = (bitH + 0.8f * th)/2;

		pg.beginDraw();
		pg.background(clearColor);
		pg.strokeWeight(2);
		pg.stroke(foreColor);
		pg.translate(bitW, bitH);
		pg.fill(foreColor);
		int bn = 31;
		for(int bit = 7; bit >= 2; bit--){
			for(int ch = 1; ch < 4; ch++){
				String channel = "" + "ARGB".charAt(ch);
				drawBit(pg, bn--, channel + bit, bcols[ch]);
			}
		}
		while(bn >= 0){
			drawBit(pg, bn--, "0", color(255));
		}
		pg.endDraw();

		return pg;
	}

	public PGraphics drawPixel6(){
		bitW = 18;
		bitH = 16;
		th = 12;
		PGraphicsJava2D pg = (PGraphicsJava2D) createGraphics(34 * bitW, 3 * bitH, JAVA2D);
		Font font = new Font("Courier", Font.PLAIN, th);
		pg.g2.setFont(font);
		pg.smooth();
		baseline = (bitH + 0.8f * th)/2;

		pg.beginDraw();
		pg.background(clearColor);
		pg.strokeWeight(2);
		pg.stroke(foreColor);
		pg.translate(bitW, bitH);
		pg.fill(foreColor);
		int bn = 17;
		for(int bit = 7; bit >= 2; bit--){
			for(int ch = 1; ch < 4; ch++){
				String channel = "" + "ARGB".charAt(ch);
				drawBit(pg, bn, channel + bit, bcols[ch]);
				bn--;
				if(bn == 13) bn = 31;
			}
		}
		bn = 13;
		while(bn >= 0){
			drawBit(pg, bn--, "0", color(255));
		}
		pg.endDraw();

		return pg;
	}

	void drawBit(PGraphicsJava2D pg, int bitPos, String text, int backCol) {
		int px = (31 - bitPos) * bitW;
		tw = pg.textWidth(text);
		pg.fill(backCol);
		pg.stroke(foreColor);
		pg.rect(px, 0, bitW, bitH);
		pg.fill(textColor);
		pg.text(text, px + (bitW - pg.textWidth(text))/2, baseline);
	}


	public PGraphics drawByte(String bits){
		bitW = 34;
		bitH = 20;
		PGraphicsJava2D pg = (PGraphicsJava2D) createGraphics(10 * bitW, 3 * bitH, JAVA2D);
		Font font = new Font("Courier", Font.BOLD, 16);
		pg.g2.setFont(font);
		pg.smooth();
		int backfill = color(192);
		foreColor = color(246,116,0);
		tw = textWidth("0");
		th = 16;
		float baseline = (bitH + 0.8f * th)/2;
		pg.beginDraw();
		pg.background(clearColor);
		pg.strokeWeight(3);
		pg.stroke(foreColor);
		pg.translate(0, bitH);
		pg.fill(foreColor);
		pg.text("MSB", 1, baseline);
		pg.text("LSB", 9 * bitW + 4, baseline);
		for(int i = 0; i < 8; i++){
			pg.translate(bitW, 0);
			pg.fill(backfill);
			pg.rect(0,0,bitW,bitH);
			pg.fill(textColor);
			pg.text(bits.charAt(i), (bitW - tw)/ 2, baseline);
		}
		pg.endDraw();
		return pg;
	}

}
